WebClient হলো Spring Framework-এর একটি আধুনিক এবং উন্নত HTTP ক্লায়েন্ট, যা Spring WebFlux মডিউলের অংশ। এটি নন-ব্লকিং (Non-blocking) এবং রিঅ্যাকটিভ (Reactive) পদ্ধতিতে কাজ করে। WebClient মূলত Spring-এর পুরনো RestTemplate
-এর বিকল্প হিসেবে ডিজাইন করা হয়েছে, এবং এটি HTTP/HTTPS প্রোটোকলের মাধ্যমে API কল করার জন্য ব্যবহৃত হয়।
GET
, POST
, PUT
, DELETE
, এবং আরও অন্যান্য সমর্থন করে।Spring Boot-এ WebClient ব্যবহার করতে নিচের ডিপেন্ডেন্সি যুক্ত করতে হবে:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
WebClient তৈরি করার জন্য তিনটি প্রধান পদ্ধতি রয়েছে:
Default WebClient:WebClient.create()
ব্যবহার করে একটি সাধারণ WebClient ইনস্ট্যান্স তৈরি করা যায়।
WebClient webClient = WebClient.create();
Base URL সহ WebClient:
একটি নির্দিষ্ট বেস URL সেট করে WebClient তৈরি করা।
WebClient webClient = WebClient.create("https://jsonplaceholder.typicode.com");
Customized WebClient:WebClient.Builder
ব্যবহার করে কাস্টম হেডার, টাইমআউট, এবং অন্যান্য কনফিগারেশন যুক্ত করা।
WebClient webClient = WebClient.builder()
.baseUrl("https://jsonplaceholder.typicode.com")
.defaultHeader("Authorization", "Bearer token")
.build();
import org.springframework.web.reactive.function.client.WebClient;
public class WebClientExample {
public static void main(String[] args) {
WebClient webClient = WebClient.create("https://jsonplaceholder.typicode.com");
String response = webClient.get()
.uri("/posts/1")
.retrieve()
.bodyToMono(String.class)
.block(); // Blocking for demonstration (not recommended in production)
System.out.println(response);
}
}
import org.springframework.web.reactive.function.client.WebClient;
import java.util.HashMap;
import java.util.Map;
public class WebClientPostExample {
public static void main(String[] args) {
WebClient webClient = WebClient.create("https://jsonplaceholder.typicode.com");
Map<String, String> requestBody = new HashMap<>();
requestBody.put("title", "foo");
requestBody.put("body", "bar");
requestBody.put("userId", "1");
String response = webClient.post()
.uri("/posts")
.bodyValue(requestBody)
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println(response);
}
}
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.WebClientResponseException;
public class WebClientErrorHandlingExample {
public static void main(String[] args) {
WebClient webClient = WebClient.create("https://jsonplaceholder.typicode.com");
try {
String response = webClient.get()
.uri("/invalid-endpoint")
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println(response);
} catch (WebClientResponseException e) {
System.err.println("Error: " + e.getStatusCode() + " - " + e.getMessage());
}
}
}
WebClient হল Spring Boot-এর আধুনিক এবং শক্তিশালী HTTP ক্লায়েন্ট। এটি মূলত উচ্চ কার্যক্ষম এবং রিঅ্যাকটিভ অ্যাপ্লিকেশন তৈরির জন্য ডিজাইন করা হয়েছে। প্রয়োজনে আরও উদাহরণ বা নির্দিষ্ট কনফিগারেশন নিয়ে আলোচনা করা যেতে পারে।
WebClient হলো Spring WebFlux-এর অংশ এবং এটি একটি আধুনিক, নন-ব্লকিং, এবং রিঅ্যাক্টিভ HTTP ক্লায়েন্ট। এটি RESTful Web Services-এর সাথে যোগাযোগ করতে ব্যবহৃত হয়। WebClient পুরোপুরি asynchronous এবং reactive স্ট্রিম সমর্থন করে। এটি ব্লকিং এবং নন-ব্লকিং উভয় প্রক্রিয়াতেই কাজ করতে পারে।
মূল বৈশিষ্ট্য:
Mono
এবং Flux
API সমর্থন করে, যা রিঅ্যাক্টিভ স্ট্রিমের অংশ।RestTemplate হলো Spring Framework-এর একটি ক্লাস যা RESTful Web Services-এর সাথে যোগাযোগ করার জন্য ব্যবহৃত হয়। এটি মূলত blocking I/O-র ওপর ভিত্তি করে কাজ করে, অর্থাৎ এটি synchronous পদ্ধতিতে কাজ করে।
মূল বৈশিষ্ট্য:
বৈশিষ্ট্য | WebClient | RestTemplate |
---|---|---|
মূল কাঠামো | Spring WebFlux | Spring MVC |
প্রোগ্রামিং মডেল | Reactive (নন-ব্লকিং এবং asynchronous) | Blocking (synchronous) |
স্ট্রিমিং সমর্থন | Reactive Streams (Mono এবং Flux ) | Reactive Streams সমর্থন করে না। |
Concurrency | একই সময় একাধিক রিকোয়েস্ট পরিচালনায় কার্যকর। | প্রতিটি রিকোয়েস্ট থ্রেড আটকে রাখে। |
পারফরম্যান্স | বেশি কনকারেন্ট কলের ক্ষেত্রে ভালো পারফরম্যান্স। | থ্রেড ব্লকিংয়ের কারণে পারফরম্যান্স কম। |
HTTP প্রোটোকল | HTTP/1.1 এবং HTTP/2 সমর্থন করে। | HTTP/1.1 সমর্থন করে। |
ভবিষ্যত | আধুনিক এবং Spring-এর রেকমেন্ডেড HTTP ক্লায়েন্ট। | Spring 5 থেকে RestTemplate deprecated। |
কনফিগারেশন | আরও উন্নত কাস্টমাইজেশন সুবিধা। | তুলনামূলকভাবে কম কাস্টমাইজেবল। |
উপযোগিতা | Reactive application বা non-blocking সিস্টেমের জন্য উপযোগী। | Traditional blocking application-এর জন্য। |
@RestController
public class RestTemplateController {
private final RestTemplate restTemplate;
public RestTemplateController(RestTemplateBuilder builder) {
this.restTemplate = builder.build();
}
@GetMapping("/fetch-data")
public String fetchData() {
String url = "https://jsonplaceholder.typicode.com/posts/1";
return restTemplate.getForObject(url, String.class);
}
}
@RestController
public class WebClientController {
private final WebClient webClient;
public WebClientController(WebClient.Builder builder) {
this.webClient = builder.baseUrl("https://jsonplaceholder.typicode.com").build();
}
@GetMapping("/fetch-data")
public Mono<String> fetchData() {
return webClient.get()
.uri("/posts/1")
.retrieve()
.bodyToMono(String.class);
}
}
ব্যবহারযোগ্য ক্ষেত্র | WebClient | RestTemplate |
---|---|---|
নতুন প্রজেক্ট বা মাইক্রোসার্ভিস আর্কিটেকচার | WebClient ব্যবহার করুন। | ব্যবহার না করার পরামর্শ। |
লিগ্যাসি সিস্টেম (Legacy Systems) | প্রয়োজনে RestTemplate থেকে WebClient-এ মাইগ্রেট করুন। | এখনও RestTemplate ব্যবহার করতে পারেন। |
Reactive Application | WebClient সবচেয়ে ভালো পছন্দ। | অপ্রাসঙ্গিক। |
Traditional Application (Blocking I/O) | WebClient ব্যবহার করা সম্ভব। | ভালো সমাধান হতে পারে। |
Spring 5 থেকে WebClient ইন্ট্রোডিউস করা হয়েছে, যা Spring WebFlux-এর অংশ। এটি একটি নন-ব্লকিং, রিয়াক্টিভ HTTP ক্লায়েন্ট এবং RestTemplate-এর আধুনিক বিকল্প হিসেবে ব্যবহৃত হয়। WebClient Spring 5 থেকে শুরু করে রিয়াক্টিভ এবং ব্লকিং উভয় ধরনের API কলের জন্য ব্যবহার করা যায়।
pom.xml
এ নিচের নির্ভরতা যোগ করুন:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
WebClient তৈরি করার দুটি প্রধান পদ্ধতি আছে:
WebClient webClient = WebClient.create();
WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.build();
২.১ GET Request:
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
@Service
public class ApiClient {
private final WebClient webClient;
public ApiClient(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://api.example.com").build();
}
public String getData(String endpoint) {
return this.webClient.get()
.uri(endpoint) // "/data"
.retrieve()
.bodyToMono(String.class) // Reactive Type
.block(); // Blocking call
}
}
২.২ POST Request:
public String postData(String endpoint, Object requestBody) {
return this.webClient.post()
.uri(endpoint)
.bodyValue(requestBody) // Request Body
.retrieve()
.bodyToMono(String.class)
.block();
}
নন-ব্লকিং পদ্ধতিতে block()
না করে Reactive Streams ব্যবহার করা হয়।
public Mono<String> getReactiveData(String endpoint) {
return this.webClient.get()
.uri(endpoint)
.retrieve()
.bodyToMono(String.class); // Returns Mono<String>
}
WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.clientConnector(new ReactorClientHttpConnector(
HttpClient.create().responseTimeout(Duration.ofSeconds(5))
))
.build();
public String getDataWithHeaders(String endpoint) {
return this.webClient.get()
.uri(endpoint)
.header("Authorization", "Bearer some-token")
.header("Custom-Header", "value")
.retrieve()
.bodyToMono(String.class)
.block();
}
public String getDataWithErrorHandling(String endpoint) {
return this.webClient.get()
.uri(endpoint)
.retrieve()
.onStatus(HttpStatus::is4xxClientError, clientResponse -> {
return Mono.error(new RuntimeException("4xx Error"));
})
.onStatus(HttpStatus::is5xxServerError, clientResponse -> {
return Mono.error(new RuntimeException("5xx Error"));
})
.bodyToMono(String.class)
.block();
}
public Flux<String> getMultipleData(String endpoint) {
return this.webClient.get()
.uri(endpoint)
.retrieve()
.bodyToFlux(String.class); // Reactive Flux
}
public Mono<Void> downloadFile(String fileUrl, String destination) {
return this.webClient.get()
.uri(fileUrl)
.retrieve()
.bodyToMono(byte[].class)
.doOnNext(bytes -> {
try {
Files.write(Paths.get(destination), bytes);
} catch (IOException e) {
e.printStackTrace();
}
})
.then();
}
Spring WebFlux-এর WebClient একটি আধুনিক HTTP ক্লায়েন্ট যা RestTemplate-এর তুলনায় আরও দক্ষ এবং রিয়াক্টিভ মডেলের জন্য আদর্শ। এটি মাইক্রোসার্ভিস এবং ক্লাউড-নেটিভ অ্যাপ্লিকেশনের জন্য বিশেষভাবে উপযোগী।
WebClient হলো Spring WebFlux-এর একটি অংশ, যা Spring Framework 5.0-এ প্রবর্তিত হয়। এটি Spring Boot অ্যাপ্লিকেশনে asynchronous এবং non-blocking HTTP কল করার জন্য ব্যবহার করা হয়। WebClient RestTemplate
-এর একটি আধুনিক বিকল্প এবং এটি রিয়্যাক্টিভ প্রোগ্রামিং এর ধারণা অনুসরণ করে।
আপনার pom.xml
ফাইলে নিচের ডিপেন্ডেন্সি যোগ করুন:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
WebClient-এর জন্য একটি Bean তৈরি করতে পারেন:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class UserClient {
private final WebClient webClient;
public UserClient(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://jsonplaceholder.typicode.com").build();
}
public Mono<String> getUserDetails() {
return webClient.get()
.uri("/users/1")
.retrieve()
.bodyToMono(String.class);
}
}
ব্যাখ্যা:
retrieve()
: রেসপন্স রিসিভ করে।bodyToMono(String.class)
: রেসপন্সকে Mono
টাইপে রূপান্তর করে, যা একক ডেটা ধারণ করে।ক্লায়েন্ট কল করার সময়:
userClient.getUserDetails().subscribe(System.out::println);
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class UserClient {
private final WebClient webClient;
public UserClient(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://jsonplaceholder.typicode.com").build();
}
public Mono<String> createUser(String name, String email) {
return webClient.post()
.uri("/users")
.bodyValue(new User(name, email))
.retrieve()
.bodyToMono(String.class);
}
}
ব্যবহার:
userClient.createUser("John Doe", "johndoe@example.com")
.subscribe(System.out::println);
WebClient-এর রেসপন্সে ত্রুটি হ্যান্ডেল করার জন্য .onStatus()
ব্যবহার করা হয়।
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class UserClient {
private final WebClient webClient;
public UserClient(WebClient.Builder webClientBuilder) {
this.webClient = webClientBuilder.baseUrl("https://api.example.com").build();
}
public Mono<String> getUserDetailsWithErrorHandling() {
return webClient.get()
.uri("/users/1")
.retrieve()
.onStatus(
status -> status.is4xxClientError(),
response -> Mono.error(new RuntimeException("Client Error"))
)
.onStatus(
status -> status.is5xxServerError(),
response -> Mono.error(new RuntimeException("Server Error"))
)
.bodyToMono(String.class);
}
}
public Mono<String> getUserDetailsWithHeaders() {
return webClient.get()
.uri("/users/1")
.header("Authorization", "Bearer token_value")
.retrieve()
.bodyToMono(String.class);
}
import java.time.Duration;
public Mono<String> getUserDetailsWithTimeout() {
return webClient.get()
.uri("/users/1")
.retrieve()
.bodyToMono(String.class)
.timeout(Duration.ofSeconds(5));
}
WebClient Mono এবং Flux ব্যবহার করে কাজ করে:
Mono<String>
Flux<String>
বৈশিষ্ট্য | WebClient | RestTemplate |
---|---|---|
Concurrency | Non-blocking, Asynchronous | Blocking, Synchronous |
Performance | উচ্চতর (Reactive Streams) | তুলনামূলক ধীর |
Reactive Support | Reactive Programming সমর্থিত | সমর্থন করে না |
Preferred For | High-performance, Microservices | Traditional, Simple HTTP Calls |
WebClient Spring Boot অ্যাপ্লিকেশনে REST API কল করার জন্য একটি আধুনিক, শক্তিশালী এবং উচ্চ কার্যক্ষম টুল। এটি বিশেষ করে রিয়্যাক্টিভ প্রোগ্রামিং এবং মাইক্রোসার্ভিস আর্কিটেকচারের জন্য উপযোগী। Asynchronous এবং Non-blocking বৈশিষ্ট্যের কারণে এটি পারফরমেন্স বৃদ্ধির ক্ষেত্রে খুবই কার্যকর।
Spring Boot WebClient একটি অত্যাধুনিক HTTP ক্লায়েন্ট, যা Spring WebFlux ফ্রেমওয়ার্কের অংশ। এটি অ্যাসিনক্রোনাস এবং রিঅ্যাকটিভ প্রোগ্রামিংয়ের জন্য উপযুক্ত। নিচে উদাহরণসহ WebClient ব্যবহার সম্পর্কে বিস্তারিত আলোচনা করা হয়েছে।
Spring Boot প্রজেক্টে WebClient ব্যবহার করতে চাইলে আগে spring-boot-starter-webflux
ডিপেন্ডেন্সি যুক্ত করুন।
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder
.baseUrl("https://api.example.com")
.build();
}
}
import org.springframework.web.reactive.function.client.WebClient;
public class WebClientGetExample {
private final WebClient webClient;
public WebClientGetExample(WebClient webClient) {
this.webClient = webClient;
}
public String fetchData() {
return webClient.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class) // Response body as String
.block(); // Blocking call (for synchronous)
}
public static void main(String[] args) {
WebClient webClient = WebClient.builder().baseUrl("https://api.example.com").build();
WebClientGetExample example = new WebClientGetExample(webClient);
String response = example.fetchData();
System.out.println("Response: " + response);
}
}
import org.springframework.web.reactive.function.client.WebClient;
public class WebClientPostExample {
private final WebClient webClient;
public WebClientPostExample(WebClient webClient) {
this.webClient = webClient;
}
public String sendData(MyRequestBody requestBody) {
return webClient.post()
.uri("/data")
.bodyValue(requestBody)
.retrieve()
.bodyToMono(String.class)
.block();
}
public static void main(String[] args) {
WebClient webClient = WebClient.builder().baseUrl("https://api.example.com").build();
WebClientPostExample example = new WebClientPostExample(webClient);
MyRequestBody requestBody = new MyRequestBody("value1", "value2");
String response = example.sendData(requestBody);
System.out.println("Response: " + response);
}
}
class MyRequestBody {
private String field1;
private String field2;
// Constructors, Getters, and Setters
public MyRequestBody(String field1, String field2) {
this.field1 = field1;
this.field2 = field2;
}
public String getField1() {
return field1;
}
public void setField1(String field1) {
this.field1 = field1;
}
public String getField2() {
return field2;
}
public void setField2(String field2) {
this.field2 = field2;
}
}
webClient.put()
.uri("/data/123")
.bodyValue(new MyRequestBody("updatedValue1", "updatedValue2"))
.retrieve()
.bodyToMono(Void.class)
.block();
webClient.delete()
.uri("/data/123")
.retrieve()
.bodyToMono(Void.class)
.block();
webClient.get()
.uri("/data")
.retrieve()
.onStatus(status -> status.is4xxClientError(),
clientResponse -> Mono.error(new RuntimeException("Client Error!")))
.onStatus(status -> status.is5xxServerError(),
clientResponse -> Mono.error(new RuntimeException("Server Error!")))
.bodyToMono(String.class)
.block();
WebClient webClient = WebClient.builder()
.baseUrl("https://api.example.com")
.defaultHeader("Authorization", "Bearer your-token-here")
.build();
String response = webClient.get()
.uri("/protected-resource")
.retrieve()
.bodyToMono(String.class)
.block();
System.out.println("Response: " + response);
import reactor.core.publisher.Flux;
public void fetchDataStream() {
Flux<String> dataStream = webClient.get()
.uri("/stream")
.retrieve()
.bodyToFlux(String.class);
dataStream.subscribe(data -> System.out.println("Received: " + data));
}
application.properties
webclient.default.read-timeout=5000
webclient.default.connect-timeout=3000
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class WebClientController {
private final WebClient webClient;
public WebClientController(WebClient webClient) {
this.webClient = webClient;
}
@GetMapping("/fetch-data")
public String fetchData() {
return webClient.get()
.uri("/data")
.retrieve()
.bodyToMono(String.class)
.block();
}
}
RestTemplate
-এর তুলনায় আরও আধুনিক এবং ফিচার-সমৃদ্ধ।Read more